package com.whh.starter.cipher;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import com.whh.starter.properties.CipherProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;

import javax.crypto.SecretKey;
import java.security.KeyPair;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * https://blog.csdn.net/Cc_Rain0624/article/details/139121745
 * 对称加密： Aes加解密
 *不对称加密：Rsa加密
 */
@Service
@ConditionalOnMissingBean(name = "cipherService")
public class CipherServiceImpl implements CipherService {
    private final CipherProperties properties ;

    public CipherServiceImpl(CipherProperties properties) {
        this.properties = properties;
    }

    protected static Map<String,String> keys(){
        Map<String,String> map = new HashMap<>(4);
        KeyPair keyPair = SecureUtil.generateKeyPair(AsymmetricAlgorithm.RSA.getValue());

        String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
        String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
        map.put("privateKey",privateKey);
        map.put("publicKey",publicKey);
        SecretKey secretKey = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue());
        map.put("secretKey",Base64.getEncoder().encodeToString(secretKey.getEncoded()));
        return map;
    }

    public static String AESEncrypt(String data, String key, CipherProperties.KeyType keyType){
        byte[] decodeKey = Base64.getDecoder().decode(key);
        AES aes = SecureUtil.aes(decodeKey);
        if(keyType.equals(CipherProperties.KeyType.BASE64)) {
            return aes.encryptBase64(data);
        }
        return aes.encryptHex(data);
    }

    public static String AESEncrypt(String data, String key){
        return AESEncrypt(data,key, CipherProperties.KeyType.BASE64);
    }

    public static String AESDecrypt(String data,String key){
        byte[] decodeKey = Base64.getDecoder().decode(key);
        AES aes = SecureUtil.aes(decodeKey);
        return aes.decryptStr(data);
    }

    public static String RSAEncrypt(String data, String publicKey, CipherProperties.KeyType keyType){
        RSA rsa = SecureUtil.rsa(null,publicKey);
        if(keyType.equals(CipherProperties.KeyType.BASE64)) {
            return rsa.encryptBase64(data, KeyType.PublicKey);
        }
        return rsa.encryptHex(data,KeyType.PublicKey);
    }
    public static String RSAEncrypt(String data, String publicKey){
        return RSAEncrypt(data,publicKey, CipherProperties.KeyType.BASE64);
    }
    public static String RSADecrypt(String data, String privateKey){
        RSA rsa = SecureUtil.rsa(privateKey,null);
        return rsa.decryptStr(data, KeyType.PrivateKey);
    }

    @Override
    public String symmetricEncrypt(String data, String secretKey) {
        return AESEncrypt(data,secretKey,properties.getKeyType());
    }

    @Override
    public String symmetricDecrypt(String data, String secretKey) {
        return AESDecrypt(data,secretKey);
    }

    @Override
    public String asymmetricEncrypt(String data, String publicKey) {
        return RSAEncrypt(data,publicKey,properties.getKeyType());
    }

    @Override
    public String asymmetricDecrypt(String data) {
        return RSADecrypt(data,properties.getPrivateKey());
    }
}
